use std::ops::Add;

use std::sync::Arc;

#[derive(Debug)]
pub struct MapNode {
    id: u32,
    x: f64,
    y: f64,
}

impl Add for &MapNode {
    type Output = f64;

    fn add(self, other: Self) -> Self::Output {
        f64::sqrt((self.x - other.x).abs().powi(2) + (self.y - other.y).abs().powi(2))
    }
}

impl MapNode {
    pub fn new(id: u32, x: f64, y: f64) -> MapNode {
        MapNode { id, x, y }
    }
    pub fn get_id(&self) -> u32 {
        self.id
    }
    pub fn get_x(&self) -> f64 {
        self.x
    }
    pub fn get_y(&self) -> f64 {
        self.y
    }
}

#[derive(Debug, Clone)]
pub struct Path {
    // 好吧...我觉得使用生命周期是不可能表达出来这个东西的
    path: Vec<Arc<MapNode>>,
}

impl Path {
    pub fn new(path: Vec<Arc<MapNode>>) -> Path {
        Path { path }
    }
    pub fn get_distance(&self) -> f64 {
        let mut result: f64 = 0 as f64;
        for i in 1..self.path.len() {
            result += &*self.path[i] + &*self.path[i - 1];
        }
        result += &**self.path.first().unwrap() + &**self.path.last().unwrap();
        result
    }
    pub fn get_raw(&self) -> &Vec<Arc<MapNode>> {
        &self.path
    }
    pub fn swap(&mut self, a1: usize, a2: usize) {
        self.path.swap(a1, a2);
    }
}

#[derive(Clone)]
pub struct Map {
    path: Vec<Arc<MapNode>>,
}

impl Map {
    pub fn new(mut path: Vec<Arc<MapNode>>) -> Map {
        path.sort_by_key(|a| a.get_id());
        Map { path }
    }
    pub fn gen_path(&self) -> Path {
        use rand::seq::SliceRandom;

        let mut rng = rand::thread_rng();
        let mut path = Vec::new();
        for node in &self.path {
            path.push(Arc::clone(node));
        }
        path.shuffle(&mut rng);

        Path { path }
    }
}
